<?php
/**
 * Created by PhpStorm.
 * User: yuanxr
 * Date: 2018/6/10
 * Time: 上午8:33
 */
namespace Utility\IO;
use Utility\Extend\EArray;
use \Exception;

/**
 * Class CSV
 * @package Utility\Convert
 */
class Csv
{
    /**
     * @var string CSV文件地址
     */
    private $path;
    private $_EArray;

    /**
     * CSV constructor.
     *
     * @param string $path CSV文件地址
     *
     */
    public function __construct(string $path)
    {
        $this->path = $path;
        $this->_EArray = new EArray();
    }

    /**
     * 读取CSV文件，并将读取结果转换为二维数组
     *
     * @param string $path 需要读取的文件的路径
     * @return array 返回解析后的数组
     */
    public function read()
    {
        // 只有正常打开文件，才继续向下进行，否则报错
        if (($file = fopen($this->path, "r")) !== false) {
            $result = [];
            while (($row = fgetcsv($file, 200, ",")) !== false) {
                $result[] = $row;
            }

            // 关闭文件，返回数据
            fclose($file);
            return $result;
        }

        // 报错
        try{
            throw new Exception('读取csv文件时出错：该.csv文件不存在，或没有读取权限！');
        }catch(Exception $e){
            echo $e->getMessage();exit();
        }

        return false;
    }

    /**
     * 将二维数组写入CSV文件（将原有文件覆盖）
     *
     * @param string $path 需要写入的文件的路径
     * @param array $data 需要写入的数组，注意：尽量是二维的（如果是一维数组，将被转换为二维数组）
     * @return void 写入数组信息到文件中
     */
    public function write(string $path, array $data)
    {
        $this->_write($path, $data, 'w+');
    }

    /**
     * 将二维数组追加到已经存在的CSV文件（不会覆盖原有文件）
     *
     * @param string $path 需要追加内容的文件的路径
     * @param array $data 需要写入的数组，注意：尽量是二维的（如果是一维数组，将被转换为二维数组）
     * @return void
     */
    public function append(string $path, array $data)
    {
        $this->_write($path, $data, 'a');
    }

    /**
     * 写入和追加方法的实际执行内部私有方法
     *
     * @param string $path 需要追加内容的文件的路径
     * @param array $data 需要写入的数组，注意：尽量是二维的（如果是一维数组，将被转换为二维数组）
     * @return void
     */
    private function _write(string $path, array $data, string $type)
    {
        // 如果data是一维数组，则被转换为二维数组
        if ($this->_EArray->depth($data) == 1) {
            $data = [$data];
        }

        // 只有正常打开文件，才继续向下进行，否则报错
        if (($file = fopen($path, $type)) !== false) {
            foreach ($data as $row) {
                fputcsv($file, $row);
            }
            fclose($file);
            return;
        }

        // 报错
        try{
            throw new Exception('写入csv文件时出错：该.csv文件不存在，或没有写入权限！');
        }catch(Exception $e){
            echo $e->getMessage();exit();
        }
    }
}
